package com.nulldev.util.java.swing.extSwing.b64Pane;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.PrivilegedAction;
import java.util.Hashtable;
import java.util.StringTokenizer;

import com.nulldev.util.java.ReflectionUtils;
import com.nulldev.util.uri.URIUtil;

@Deprecated
public class B64Handler extends URLStreamHandler {

    @Override
    protected URLConnection openConnection(URL u) throws IOException {
    	//System.out.println(u.toString());
        return new DataConnection(u);
    }

//    public static void install() {
//        String pkgName = B64Handler.class.getPackage().getName();
//        String pkg = pkgName.substring(0, pkgName.lastIndexOf('.'));
//  
//        String protocolHandlers = System.getProperty("java.protocol.handler.pkgs", "");
//        if (!protocolHandlers.contains(pkg)) {
//            if (!protocolHandlers.isEmpty()) {
//                protocolHandlers += "|";
//            }
//            protocolHandlers += pkg;
//            System.setProperty("java.protocol.handler.pkgs", protocolHandlers);
//        }
//        URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
//			
//			@Override
//			public URLStreamHandler createURLStreamHandler(String protocol) {
//				if (protocol.equals("data")) {
//					return new B64Handler();
//				}
//				return getURLStreamHandler(protocol);
//			}
//		});
//    }
    
    final static URLStreamHandlerFactory factory = (URLStreamHandlerFactory) ReflectionUtils.fetchField(
    		URIUtil.safeCreate(""), "factory");
    static Hashtable<String, URLStreamHandler> handlers = new Hashtable<String, URLStreamHandler>();
    private static Object streamHandlerLock = new Object();
    private static final String protocolPathProp = "java.protocol.handler.pkgs";
    
    static URLStreamHandler getURLStreamHandler(String protocol) {

        URLStreamHandler handler = handlers.get(protocol);
        if (handler == null) {

            boolean checkedWithFactory = false;

            // Use the factory (if any)
            if (factory != null) {
                handler = factory.createURLStreamHandler(protocol);
                checkedWithFactory = true;
            }

            // Try java protocol handler
            if (handler == null) {
                String packagePrefixList = null;

                packagePrefixList
                    = java.security.AccessController.doPrivileged(
                    (PrivilegedAction<String>) new sun.security.action.GetPropertyAction(
                        protocolPathProp,""));
                if (packagePrefixList != "") {
                    packagePrefixList += "|";
                }

                // REMIND: decide whether to allow the "null" class prefix
                // or not.
                packagePrefixList += "sun.net.www.protocol";

                StringTokenizer packagePrefixIter =
                    new StringTokenizer(packagePrefixList, "|");

                while (handler == null &&
                       packagePrefixIter.hasMoreTokens()) {

                    String packagePrefix =
                      packagePrefixIter.nextToken().trim();
                    try {
                        String clsName = packagePrefix + "." + protocol +
                          ".Handler";
                        Class<?> cls = null;
                        try {
                            cls = Class.forName(clsName);
                        } catch (ClassNotFoundException e) {
                            ClassLoader cl = ClassLoader.getSystemClassLoader();
                            if (cl != null) {
                                cls = cl.loadClass(clsName);
                            }
                        }
                        if (cls != null) {
                            handler  =
                              (URLStreamHandler)cls.newInstance();
                        }
                    } catch (Exception e) {
                        // any number of exceptions can get thrown here
                    }
                }
            }

            synchronized (streamHandlerLock) {

                URLStreamHandler handler2 = null;

                // Check again with hashtable just in case another
                // thread created a handler since we last checked
                handler2 = handlers.get(protocol);

                if (handler2 != null) {
                    return handler2;
                }

                // Check with factory if another thread set a
                // factory since our last check
                if (!checkedWithFactory && factory != null) {
                    handler2 = factory.createURLStreamHandler(protocol);
                }

                if (handler2 != null) {
                    // The handler from the factory must be given more
                    // importance. Discard the default handler that
                    // this thread created.
                    handler = handler2;
                }

                // Insert this handler into the hashtable
                if (handler != null) {
                    handlers.put(protocol, handler);
                }

            }
        }

        return handler;

    }
}
